package com.pheruagor.handmanager.storage.impl.sqlite {
    import com.pheruagor.handmanager.model.business.Member;
    import com.pheruagor.handmanager.model.business.activity.Activity;
    import com.pheruagor.handmanager.model.business.activity.PlayerActivity;
    import com.pheruagor.handmanager.storage.api.MemberStorage;
    import com.pheruagor.handmanager.storage.api.PlayerActivityStorage;

    import flash.data.SQLResult;
    import flash.data.SQLStatement;
    import flash.errors.SQLError;
    import flash.events.SQLEvent;

    import mx.collections.ArrayCollection;

    public class MemberSQLiteStorage implements MemberStorage {
        //-----------------------------------------------------
        // Properties
        //-----------------------------------------------------
        private var m_table:Table;
        private var m_playerActivityStorage:PlayerActivityStorage;
        private var m_storage:SQLiteStorage;

        //-----------------------------------------------------
        // Initialization
        //-----------------------------------------------------

        public function MemberSQLiteStorage() {
            createTable();
            m_playerActivityStorage = new PlayerActivitySQLiteStorage();
            m_storage = new SQLiteStorage;
        }

        private function createTable():void {
            m_table = new Table('member');
            m_table.creationStatement = "( id TEXT PRIMARY KEY,"
                + " clubId TEXT CONSTRAINT fk_club_id REFERENCES club(id), forname VARCHAR(64),"
                + " lastname VARCHAR(64), birthday TEXT, size INTEGER(3), geneticHand VARCHAR(8),"
                + " gender VARCHAR(8), avatarPath TEXT, clubEntryDate TEXT, subscription INTEGER, phoneNumber VARCHAR(10))";
        }

        //-----------------------------------------------------
        // Access
        //-----------------------------------------------------
        private function get table():Table {
            return m_table;
        }

        //-----------------------------------------------------
        // Operation
        //-----------------------------------------------------
        public function saveMember(member:Member, onResult:Function = null, onFault:Function = null):void {
            if (member == null) {
                throw new ArgumentError("member cannot be null");
            }
            if (member.id == null) {
                throw new ArgumentError("member id cannot be null");
            }
            if (member.clubId == null) {
                throw new ArgumentError("club id cannot be null or empty");
            }

            saveActivity(member, onResult, onFault);
        }

        /**
         * Remove the member and all the related activities
         */
        public function removeMember(member:Member, onResult:Function = null, onFault:Function = null):void {
            if (member == null) {
                throw new ArgumentError("member cannot be null");
            }
            if (member.id == null) {
                throw new ArgumentError("member id cannot be null");
            }

            // remove all activities related to the member
            if (member.activities != null && member.activities.length > 0) {
                var activities:Array = member.activities.source.concat();
                var playerActivityStorage:PlayerActivitySQLiteStorage = new PlayerActivitySQLiteStorage();
                for each (var activity:Activity in activities) {
                    if (activity is PlayerActivity) {
                        var playerActivity:PlayerActivity = PlayerActivity(activity);
                        playerActivityStorage.removeActivity(activity.id);
                    }
                }
            }
            var resultHandler:Function = function(event:SQLEvent):void {
                    if (onResult != null) {
                        onResult();
                    }
                }
            var faultHandler:Function = function(event:SQLError):void {
                    if (onFault != null) {
                        onFault();
                    }
                }
            table.removeStatement = "WHERE id='" + member.id + "';";
            m_storage.remove(table, resultHandler, faultHandler);
        }

        public function listMembers(clubId:String, onResult:Function, onFault:Function = null):void {
            if (clubId == null || clubId.length == 0) {
                throw new ArgumentError("clubId cannot be null or empty");
            }
            var resultHandler:Function = function(event:SQLEvent):void {
                    if (onResult != null) {
                        var sqlResult:SQLResult = SQLStatement(event.currentTarget).getResult();
                        if (sqlResult.data == null) {
                            onResult(null);
                            return;
                        }
                        var memberItems:Array = sqlResult.data.concat();
                        var memberList:Array = new Array();
                        // Build the member list as the result
                        if (memberItems.length > 0) {
                            // Create Member object with storage to application convertion
                            var activityStorage:PlayerActivitySQLiteStorage = new PlayerActivitySQLiteStorage();
                            // Add activities for each member
                            for each (var memberItem:Object in memberItems) {
                                var member:Member = Member.fromObject(memberItem);
                                memberList.push(member);
                                var onActivityResult:Function = function(activities:Array):void {
                                        member.activities = new ArrayCollection(activities);
                                    };
                                var onActivityFault:Function = function():void {
                                        if (onFault != null) {
                                            onFault();
                                        }
                                    };
                                activityStorage.listActivities(member, onActivityResult, onActivityFault);
                            }
                        }
                        if (onResult != null) {
                            onResult(memberList);
                        }
                    }
                }
            var faultHandler:Function = function():void {
                    if (onFault != null) {
                        onFault();
                    }
                }

            table.selectStatement = "* FROM " + table.name + " WHERE clubId='" + clubId + "';";
            m_storage.load(table, resultHandler, faultHandler);
        }

        public function removeAllMembersFromClub(clubId:String, onResult:Function = null, onFault:Function = null):void {
            if (clubId == null || clubId.length == 0) {
                throw new ArgumentError("clubId cannot be null or empty");
            }
            table.removeStatement = " WHERE clubId='" + clubId + "';";
            var resultHandler:Function = function(event:SQLEvent):void {
                    if (onResult != null) {
                        onResult();
                    }
                }
            var faultHandler:Function = function():void {
                    if (onFault != null) {
                        onFault();
                    }
                }

            m_storage.remove(table, resultHandler, faultHandler);
        }

        public function removeAllMembers(onResult:Function = null, onFault:Function = null):void {
            table.removeStatement = ";";
            var resultHandler:Function = function(event:SQLEvent):void {
                    if (onResult != null) {
                        onResult();
                    }
                }
            var faultHandler:Function = function():void {
                    if (onFault != null) {
                        onFault();
                    }
                }

            m_storage.remove(table, resultHandler, faultHandler);
        }

        //-----------------------------------------------------
        // Implementation
        //-----------------------------------------------------
        private function saveActivity(member:Member, onResult:Function, onFault:Function = null):void {
            if (member.activities != null && member.activities.length > 0) {
                var resultHandler:Function = function(event:SQLEvent):void {
                        saveMemberInternal(member, onResult, onFault);
                    }
                var faultHandler:Function = function():void {
                        if (onFault != null) {
                            onFault();
                        }
                    };
                var playerActivity:PlayerActivity = member.activities.getItemAt(0) as PlayerActivity;
                if (playerActivity != null) {
                    m_playerActivityStorage.saveActivity(playerActivity, resultHandler, faultHandler);
                }
            } else {
                saveMemberInternal(member, onResult, onFault);
            }
        }

        private function saveMemberInternal(member:Member, onResult:Function, onFault:Function = null):void {
            var birthday:String = member.birthday == null ? null : member.birthday.toString();
            var clubEntryDate:String = member.clubEntryDate == null ? null : member.clubEntryDate.toString();
            var size:int = isNaN(member.size) ? -1 : member.size;
            var subscription:Number = isNaN(member.subscription) ? -1 : member.subscription;
            var phoneNumber:String = member.phoneNumber == null ? null : member.phoneNumber;
            table.insertStatement
                = "(id, clubId, forname, lastname, birthday, size, geneticHand, gender, avatarPath, clubEntryDate, subscription, phoneNumber) values('"
                + member.id + "','" + member.clubId + "','" + member.forname + "','" + member.lastname + "','" + birthday + "'," + size
                + ",'" + member.geneticHand + "','" + member.gender + "','" + member.avatarPath + "','" + clubEntryDate + "',"
                + subscription + ",'" + phoneNumber + "');";
            var resultHandler:Function = function(event:SQLEvent):void {
                    if (onResult != null) {
                        onResult(event);
                    }
                }
            var faultHandler:Function = function():void {
                    if (onFault != null) {
                        onFault();
                    }
                }
            m_storage.save(table, resultHandler, faultHandler);
        }

    }

}